#ifndef __SOMMET
#define __SOMMET
#include "face.hpp"
#include <iostream>

class Face;
class Sommet
{
	private:
		int id;
		Face* face;
		double x;
		double y;
		double z;
		
	public:
		Sommet():id(0),x(0),y(0),z(0){};
		Sommet(int i,double xx, double yy, double zz):id(i),x(xx),y(yy),z(zz){};
		~Sommet(){};
		double getX();
		double getY();
		double getZ();
		int getId();
		Face* getFace() const;
		void setFace(Face* f);
		//surchage de l'operateur ==
		bool operator==(const Sommet& s)const;
		
		//surchage de l'affichage
		friend std::ostream& operator<<(std::ostream& out, const Sommet& b);
		
		//itérateur sur les sommets adjacents dans le sens inverse des aiguilles d'une montre
		class IterSommetAdj
		{
			private:
				Sommet* s;
				Face* f;
				bool fin;
				
			public:
			IterSommetAdj(){};
			IterSommetAdj(Sommet* ss,bool x=false):s(ss),f(ss->getFace()),fin(x){}
			IterSommetAdj(Face* ff,Sommet* ss,bool x=false):s(ss),f(ff),fin(x){}
			~IterSommetAdj(){}
			
			void operator++();
			void operator++(int=1);
			bool operator==(const IterSommetAdj& is);
			bool operator!=(const IterSommetAdj& is);
			Sommet& operator*();
		};
		
		//itérateur sur les faces adjacentes dans le sens inverse des aiguilles d'une montre
		class IterFaceAdj
		{
			private:
				Sommet* s;
				Face* f;
				bool fin;
				
			public:
			IterFaceAdj(){};
			IterFaceAdj(Sommet* ss,bool x=false):s(ss),f(ss->getFace()),fin(x){}
			IterFaceAdj(Face* ff,Sommet* ss,bool x=false):s(ss),f(ff),fin(x){}
			~IterFaceAdj(){}
			
			void operator++();
			void operator++(int=1);
			bool operator==(const IterFaceAdj& is);
			bool operator!=(const IterFaceAdj& is);
			Face& operator*();
		};
		
		//permet de se positionner sur le premier sommet adjacent
		IterSommetAdj beginSommetAdj()
		{
			return IterSommetAdj(this,false);
		}

		//permet de se positionner sur le dernier sommet adjacent
		IterSommetAdj endSommetAdj()
		{
			return IterSommetAdj(this,true);
		}

		//permet de se positionner sur la premiere face adjacent
		IterFaceAdj beginFaceAdj()
		{
			return IterFaceAdj(this,false);
		}

		//permet de se positionner sur la derniere face adjacent
		IterFaceAdj endFaceAdj()
		{
			return IterFaceAdj(this,true);
		}
};

#endif
